package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.itheima.constant.MessageConstant;
import com.itheima.constant.RedisMessageConstant;
import com.itheima.entity.Result;
import com.itheima.pojo.Member;
import com.itheima.service.MemberService;
import com.itheima.service.OrderService;
import com.itheima.utils.DateUtils;
import com.itheima.utils.RSAUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.JedisPool;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 处理会员相关操作
 */
 //注释

@RestController
@RequestMapping("/member")
public class MemberController {
    @Autowired
    private JedisPool jedisPool;
    @Reference
    private OrderService orderService;
    @Reference
    private MemberService memberService;

    //手机号快速登录
    @RequestMapping("/login")
    public Result login(HttpServletResponse response, @RequestBody Map map){

        String telephone = (String) map.get("telephone");
        String validateCode = (String) map.get("validateCode");
        //从Redis中获取保存的验证码
        String validateCodeInRedis = jedisPool.getResource().get(telephone + RedisMessageConstant.SENDTYPE_LOGIN);
        // 1>0,没有使用验证码,直接跳过验证
        if(1>0||validateCodeInRedis != null && validateCode != null && validateCode.equals(validateCodeInRedis)){
            //验证码输入正确
            //判断当前用户是否为会员（查询会员表来确定）
            Member member = memberService.findByTelephone(telephone);
            if(member == null){
                member=new Member();
                //member，自动完成注册（自动将当前用户信息保存到会员表）
                member.setRegTime(new Date());
                member.setPhoneNumber(telephone);
                // todo 添加会员后拿不到id
                memberService.add(member);
            }
            // 使用Rsa加密
            Map<String, String> rsaWork = RSAUtils.doRSAWork(telephone);
            if (rsaWork==null){
                // rsa加密失败
                return new Result(false,"请联系管理员");
            }
            // 私钥
            String privateKey = rsaWork.get("privateKey");
            // 加密后的密文
            String messageEn = rsaWork.get("messageEn");
            //向客户端浏览器写入Cookie，值为加密后的手机号
            Cookie cookie = new Cookie("login_member_telephone",messageEn);
            cookie.setPath("/");
            cookie.setMaxAge(60*60*24*30);
            response.addCookie(cookie);
            //将会员信息和私钥保存到Redis
            Map<String,Object> redisMap = new HashMap();
            redisMap.put("data",member);
            redisMap.put("privateKey",privateKey);
            String json = JSON.toJSON(redisMap).toString();
//            jedisPool.getResource().setex(telephone+RedisMessageConstant.SENDTYPE_LOGIN,60*30,json);
            jedisPool.getResource().setex(messageEn,60*30,json);
            return new Result(true,MessageConstant.LOGIN_SUCCESS);
        }else{
            //验证码输入错误
            return new Result(false, MessageConstant.VALIDATECODE_ERROR);
        }
    }
    //进入任何页面都要执行该方法
    @RequestMapping("/findMemberByCookie")
    public Result findMemberByCookie(HttpServletRequest request) {
        Result r = getCookieAsMember(request);
        if (!r.isFlag()){
            // 重新登录
            r.setData("login.html");
            return r;
        }
        Member member = (Member) r.getData();
        return new Result(true,MessageConstant.GET_USERNAME_SUCCESS,member);
    }
    //更新用户信息
    @RequestMapping("/save")
    public Result saveMember(HttpServletRequest request,@RequestBody Member member){
        try {
            // 以新修改的手机号查询是否有会员信息存在
            Member byTelephone = memberService.findByTelephone(member.getPhoneNumber());
            if (byTelephone==null){
                // 通过身份证号设置生日
                String idCard = member.getIdCard();
                if (idCard != null) {
                    Map<String, String> birAgeSex = DateUtils.getBirAgeSex(member.getIdCard());
                    String birthday = birAgeSex.get("birthday");
                    member.setBirthday(DateUtils.parseString2Date(birthday));
                }
                // 如果没查询到数据.说明可以修改
                memberService.update(member);
                //用户更改了手机号,需要清除redis并重新登录
                Cookie[] cookies = request.getCookies();
                Cookie inMemberCookie = null;
                // 查询浏览器的cookie中是否有用户登录的信息
                for (Cookie cookie : cookies) {
                    if ("login_member_telephone".equals(cookie.getName())){
                        // cookie中有对应的数据
                        inMemberCookie=cookie;
                        break;
                    }
                }
                if (inMemberCookie==null){
                    // 用户没有登录,跳转到登录页面
                    return new Result(false,MessageConstant.GET_USERNAME_FAIL);
                }
                //cookie中有用户数据,取出后和redis中的对比看是否能取得对应的数据
                String cookieValue = inMemberCookie.getValue();
                //从redis中移除数据
                jedisPool.getResource().del(cookieValue);
//                jedisPool.getResource().setex(cookieValue,0,null);
//                jedisPool.getResource().srem(cookieValue);
                return new Result(true,MessageConstant.EDIT_MEMBER_SUCCESS,member);
            }
            else if(byTelephone.getId().equals(member.getId())){
                // 通过身份证号设置生日
                String idCard = member.getIdCard();
                if (idCard != null) {
                    Map<String, String> birAgeSex = DateUtils.getBirAgeSex(member.getIdCard());
                    String birthday = birAgeSex.get("birthday");
                    member.setBirthday(DateUtils.parseString2Date(birthday));
                }
                //或者查出的id和提交是一致的,可以修改,但是不需要删除redis
                memberService.update(member);
                return new Result(true,MessageConstant.EDIT_MEMBER_SUCCESS,member);
            }
            else {
                // 否则该手机号已经存在
                return new Result(false,MessageConstant.EDIT_MEMBER_FAIL_ISHAVE);
            }

        }catch (Exception e){
            return new Result(false,MessageConstant.EDIT_MEMBER_FAIL);
        }
    }

    @RequestMapping("/savePwd")
    public Result savePwd(HttpServletRequest request,@RequestBody Map<String,String> map){
        try {
            // 获取cookie中的手机号加密后的值
            Result r = getCookieAsMember(request);
            if (r.isFlag()){
//                //从cookie中获取信息
                Member redisMember = (Member) r.getData();
                // 从数据库中查询最新的数据
                Member member = memberService.findByTelephone(redisMember.getPhoneNumber());
                //更新redis中的数据

                // 把数据库的中密码添加到map中
                map.put("oldPwdInDb",member.getPassword());
                map.put("memberId",member.getId().toString());
                return memberService.savePwd(map);
            }else {
                return r;
            }

        }catch (Exception e){
            return new Result(false,MessageConstant.UPDATE_PASSWORD_FAIL);
        }
    }
    //预约历史的列表页面
    @RequestMapping("/findHistorySetmeal")
    public Result findHistorySetmeal(HttpServletRequest request,@RequestBody Map<String,String> data){
        Result r = getCookieAsMember(request);
        // cookie中没有数据,直接跳转到登录页面
        if (!r.isFlag()) {
            r.setData("login.html");
            return r;
        }
        String start = data.get("startDate");
        String end = data.get("endDate");
        // 从redis中获取用户的id
        Member member = (Member) r.getData();
        Map<String,Object> map=new HashMap<>();
        map.put("member",member);
        map.put("start",start);
        map.put("end",end);

        List<Map<String, Object>> list = memberService.findHistorySetmeal(map);
        return new Result(true,"获取成功",list);
    }
    @RequestMapping("/findOrderDetailById")
    public Result findOrderDetailById(Integer id){
        try {
            Map<String,Object> map = orderService.findOrderDetail4MemberHisById(id);
            return new Result(true,MessageConstant.ORDER_DETAIL_SUCCESS,map);
        }catch (Exception e){
            return new Result(false,MessageConstant.ORDER_DETAIL_FAIL);
        }
    }
    /**
     * 通过加密后的cookie获取redis中保存的用户信息
     * @param request request
     * @return member对象/无数据需要登录
     */
    public Result getCookieAsMember(HttpServletRequest request){
        Cookie[] cookies = request.getCookies();
        Cookie inMemberCookie = null;
        // 查询浏览器的cookie中是否有用户登录的信息
        for (Cookie cookie : cookies) {
            if ("login_member_telephone".equals(cookie.getName())){
                // cookie中有对应的数据
                inMemberCookie=cookie;
                break;
            }
        }
        if (inMemberCookie==null){
            // 用户没有登录,跳转到登录页面

            return new Result(false,MessageConstant.GET_USERNAME_FAIL);
        }
        //cookie中有用户数据,取出后和redis中的对比看是否能取得对应的数据
        String cookieValue = inMemberCookie.getValue();

        //使用加密后的值作为key从redis中取数据
        String redisData = jedisPool.getResource().get(cookieValue);
        if (redisData==null){
            return new Result(false,MessageConstant.GET_USERNAME_FAIL);
        }
        Map map = JSON.parseObject(redisData, Map.class);
        // todo 改map提取出来的对象不能转为String，而要通过它的方法 toString 来转化：
        // https://www.cnblogs.com/zhumengdexiaobai/p/10480550.html
        String data = map.get("data").toString();
        Member member = JSON.parseObject(data, Member.class);
        return new Result(true,"",member);
    }

}
